#Rem
	header: AGFX Box2d implementation for TILED
#End
Strict
Import mojo
Import agfx


#Rem
summary: TTiled_Physics
#End
Class TTiled_Physics

	Private
	Field _map_data:		TTiled_Map
	

	Public
	
	#Rem
	summary: Box2D world
	#End
	Field collision:		TBox2DWrapper
	
	#Rem
	summary: box2d state 
	#End
	Field box2d_use:		Bool=False

	#Rem
	summary: box2d debug state
	#End
	Field box2d_debug:		Bool=False

	#Rem
	summary: box2d world gravity
	#End
	Field box2d_gravity:	b2Vec2 = New b2Vec2(0,10)


	#Rem
	summary: Constructor
	mapdata:TTiled_Map - reference to level data
	#End
	Method New(mapdata:TTiled_Map,dbg:Bool)
		
		Self._map_data = mapdata
		Self.box2d_debug = dbg
		
		' check MAP properties		
		If Self._map_data.properties.Has("box2d") Then	Self.box2d_use = True
		

		if Self._map_data.properties.Has("gravity") Then
			Local grav:TProperty = Self._map_data.properties.Get("gravity")
			Local gravity:b2Vec2
			Self.box2d_gravity = New b2Vec2(grav.ToVector().x,grav.ToVector().y)
		Else
			Self.box2d_gravity = New b2Vec2(0,10)
		EndIf
		
		' Create Box2D when is enabled
		If Self.box2d_use Then							
			If DEBUG Then Print("TILED PHYSICS: Enabled")			
			Self.collision 		= New TBox2DWrapper()
			Self.collision.CreateWorld(Self.box2d_gravity,True,100,Self.box2d_debug)		
		End If		
	End

	#Rem
	summary: Load polygon shape templates from tileset
	#End
	Method LoadCollisionShapeTemplates:Void(tilesets_name:String)
	
		Local tileset:TTiled_Tileset = Self._map_data.GetTilesetsByName(tilesets_name)
		Local tile:TTiled_TilesetTile
		
		For tile = EachIn tileset.tiles
		
			If tile.properties.Has("b2d_shape")	Then
				Local shape_poly_name:String = tile.properties.Get("b2d_shape").ToString()
				If shape_poly_name<>"box" and shape_poly_name<>"circle" Then Self.collision.AddPolygonShapeTemplate(shape_poly_name)
			End If
		
		Next
	End


	#Rem
	summary: Create/convert collision layer to Box2D World
	#End
	Method BuildCollisionWorld:Void(layer_name:String)
		
		Local coll_layer:TTiled_Layer = Self._map_data.GetLayerByName(layer_name)
		
		Local static_fixture:b2FixtureDef = New b2FixtureDef()
			
		static_fixture.density 		= 0
		static_fixture.restitution 	= 0.3
		static_fixture.friction 	= 0.3
			
		' build static collision shapes
		For Local x:Int=0 To coll_layer.width-1
			For Local y:Int=0 To coll_layer.height-1

				
				Local tile:TTiled_LayerTile = coll_layer.GetTile(x,y)
				Local px:Float = tile.tilewidth*x + tile.tilewidth/2.0
				Local py:Float = tile.tileheight*y + tile.tileheight / 2.0
				
				
				If tile.id>0 Then
					
					If tile.tileset_tile Then
					
						Local shape_name:String = tile.tileset_tile.properties.Get("b2d_shape").ToString()
						Local shape_type:String = tile.tileset_tile.properties.Get("b2d_shape_type").ToString()
						
						Select shape_type
							Case "polygon"
								Local vertices:FlashArray<b2Vec2> = Self.collision.poly_shapes.Get(shape_name)						
								Self.collision.CreateStaticPolygon(shape_name+"_"+x+"_"+y,px,py,tile.tilewidth,tile.tileheight,vertices)	
							Case "default"
							
								Select shape_type
									Case "box"
										Self.collision.CreateStaticBox("BOX_"+x+"_"+y,px,py,tile.tilewidth,tile.tileheight)
									Case "circle"
										Self.collision.CreateStaticCircle("CIRCLE_"+x+"_"+y,px,py,tile.tilewidth/2.0)
									Default 
										Self.collision.CreateStaticBox("BOX_"+x+"_"+y,px,py,tile.tilewidth,tile.tileheight)
								End Select 
								
						End Select
					
					EndIf
					
				EndIF


			Next
		Next
	End Method

	#Rem
	summary: Update
	#End
	Method Update:Void()
		If Self.box2d_use Then Self.collision.Update()
	End

	#Rem
	summary: Render
	#End
	Method Render:Void()
		If Self.box2d_use Then Self.collision.Render()

	End

End